/*
 * Galaxium Messenger
 * Copyright (C) 2005-2007 Ben Motmans <ben.motmans@gmail.com>
 * 
 * License: GNU General Public License (GPL)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

using System;
using System.Collections.Generic;

using Mono.Addins;

using Gtk;
using Gdk;
using Anculus.Core;

using Galaxium.Core;
using Galaxium.Gui;

namespace Galaxium.Gui.GtkGui
{
	public enum PixbufRendererFrameSize
	{
		Small,
		Medium,
		Large,
		Huge,
		Info
	}
	
	public static class IconUtility
	{
		private static IconManager<Pixbuf> _iconManager;
		private static IconManager<PixbufAnimation> _animationManager;
		
		public static void Initialize ()
		{
			Log.Debug ("Initializing icon utility...");
			
			Initialize (IconManager<Pixbuf>.DefaultTheme);
		}

		public static void Initialize (string theme)
		{
			ThrowUtility.ThrowIfEmpty ("theme", theme);
			
			Log.Debug ("Initializing icon & animation theme: "+theme);
			
			_iconManager = new IconManager<Pixbuf> (new GtkIconThemeLoader (), new RescaleIconTypeHandler<Pixbuf> (PixbufRescaleHandler));
			_iconManager.RegisterDefaultIconSizes ();
			
			_animationManager = new IconManager<PixbufAnimation> (new GtkAnimationThemeLoader (), new RescaleIconTypeHandler<PixbufAnimation> (AnimationRescaleHandler));
			_animationManager.RegisterDefaultIconSizes ();
			
			_iconManager.Theme = theme;
			_animationManager.Theme = theme;
		}

		public static string Theme
		{
			get { return _iconManager.Theme; }
			set { _iconManager.Theme = value; }
		}
		
		public static Gui.IIconSize ParseIconSize (string identifier)
		{
			return _iconManager.ParseIconSize (identifier);
		}
		
		public static Pixbuf GetIcon (string name)
		{
			return _iconManager.GetIcon (name);
		}
		
		public static PixbufAnimation GetAnimation (string name)
		{
			return _animationManager.GetIcon (name);
		}
		
		public static Pixbuf GetIcon (string name, IIconSize iconSize)
		{
			return _iconManager.GetIcon (name, iconSize);
		}
		
		public static PixbufAnimation GetAnimation (string name, IIconSize iconSize)
		{
			return _animationManager.GetIcon (name, iconSize);
		}
		
		public static Pixbuf GetIcon (string theme, string name)
		{
			return _iconManager.GetIcon (theme, name);
		}
		
		public static PixbufAnimation GetAnimation (string theme, string name)
		{
			return _animationManager.GetIcon (theme, name);
		}

		public static Pixbuf GetIcon (string theme, string name, IIconSize iconSize)
		{
			return _iconManager.GetIcon (theme, name, iconSize);
		}
		
		public static PixbufAnimation GetAnimation (string theme, string name, IIconSize iconSize)
		{
			return _animationManager.GetIcon (theme, name, iconSize);
		}
		
		public static IIconSize GetCorrespondingIconSize (IconSize iconSize)
		{
			switch (iconSize) {
				case IconSize.Button:
				case IconSize.Dnd:
				case IconSize.SmallToolbar:
				case IconSize.Menu:
					return IconSizes.Small;
				case IconSize.Dialog:
					return IconSizes.Large;
				case IconSize.LargeToolbar:
					return IconSizes.Medium;
				case IconSize.Invalid:
				default:
					return IconSizes.Other;
			}
		}
		
		private class GtkAnimationThemeLoader : IIconThemeLoader<PixbufAnimation>
		{
			public IEnumerable<IconExtension<PixbufAnimation>> LoadIcons (string theme)
			{
				IEnumerable<ContextExtension> nodes = AddinUtility.GetContextExtensionNodes ("/Galaxium/Animations", new DefaultExtensionContext(), typeof(IconExtension<PixbufAnimation>));
				foreach (GtkAnimationExtension node in nodes)
				{
					yield return node;
				}
			}
		}
		
		private class GtkIconThemeLoader : IIconThemeLoader<Pixbuf>
		{
			public IEnumerable<IconExtension<Pixbuf>> LoadIcons (string theme)
			{
				IEnumerable<ContextExtension> nodes = AddinUtility.GetContextExtensionNodes ("/Galaxium/Icons", new DefaultExtensionContext(), typeof(IconExtension<Pixbuf>));
				foreach (GtkIconExtension node in nodes)
				{
					yield return node;
				}
			}
		}
		
		private static PixbufAnimation AnimationRescaleHandler (PixbufAnimation animation, IIconSize size)
		{
			if (size.Size <= 0)
				return animation;
			
			//FIXME: we cannot resize the animation?
			
			return animation;
		}
		
		private static Pixbuf PixbufRescaleHandler (Pixbuf pixbuf, IIconSize size)
		{
			if (size.Size <= 0)
				return pixbuf;
			
			return pixbuf.ScaleSimple (size.Size, size.Size, InterpType.Bilinear);
		}
	}
}